#include"FunctionDeclaration.h"
void prompt() {
	printf(" \n\t                                  \n");
	printf(" \n\t本程序，主要演示各级别菜单的调用过程");
	printf(" \n\t希望你认真阅读菜单的书写方法，并修改你的程序\n");
	printf(" \n\t                                              ");
	printf(" \n\t                        \n");
	printf(" \n\t再一次提醒，你看的主要是菜单程序！");
	printf(" \n\t-------------------------------------------------");
	printf("\n\t好的，让我们开始吧！\n\n");
	system("pause");
}

void menu(Node_S* phead) {
	while (1) {
		system("CLS");
		printf("\n\t\t   学生管理软件");
		printf("\n\t\t--------------------");
		printf("\n\t\t   1 数据输入 <好用>");
		printf("\n\t\t   2 数据输出 <好用>");
		printf("\n\t\t   3 数据统计 <好用>");
		printf("\n\t\t   4 数据查询（*模拟）");
		printf("\n\t\t   5 数据排序（*模拟）");
		printf("\n\t\t   6 数据插入（*模拟）");
		printf("\n\t\t   7 数据删除 <好用>");
		printf("\n\t\t   8 数据修改（*模拟）");
		printf("\n\t\t   9 数据储存（*模拟）");
		printf("\n\t\t   0 退出");
		printf("\n\t\t--------------------");
		printf("\n\t\t   请选择(0-9): ");
		int option;
		scanf("%d", &option);
		switch (option) {
			case 0: {
				return;
			}
			case 1: {
				printf("\n建结点个数n=");
				int n;
				scanf("%d", &n);
				phead = createList(phead, n);
				break;
			}
			case 2: {
				traversal(phead);
				break;
			}
			case 3: {
				menu1(phead);
				break;
			}
			case 4: {
				menu2(phead);
				break;
			}
			case 5: {
				menu3(phead);
				break;
			}
			case 6: {
				menu4(phead);
				break;
			}
			case 7: {
				menu5(phead);
				break;
			}
			case 8: {
				printf("\n进入修改学生信息模块.......");
				Change(phead);
				break;
			}
			case 9: {
				printf("\n进入数据存储模拟模块.......");
				DataSave(phead);
				printf("\n文件存入Student_File.dat中");
				break;
			}
		default:
			continue;
		}
		system("pause");
	}
	return;
}



void menu1(Node_S* phead) {
	while (1) {
		system("CLS");
		printf("\n\t\t   学生管理统计功能");
		printf("\n\t\t--------------------");
		printf("\n\t\t   1 按性别统计学生的人数");
		printf("\n\t\t   2 统计年龄对应的人数");
		printf("\n\t\t   3 统计民族对应的学生人数");
		printf("\n\t\t   4 统计年龄对应的学生");
		printf("\n\t\t   5 统计民族对应的学生");
		printf("\n\t\t   0 退出");
		printf("\n\t\t--------------------");
		printf("\n\t\t   请选择(0-5): ");
		int option;
		scanf("%d", &option);
		switch (option) {
			case 0: {
				return;
			}
			case 1: {
				int count1;
				count1 = countGender(phead);
				printf("\n该性别学生的人数：%d\n", count1);
				system("pause");
				break;
			}
			case 2: {
				int count2;
				count2 = countAge(phead);
				printf("\n该年龄学生的人数为：%d\n", count2);
				system("pause");
				break;
			}
			case 3: {
				int count3;
				count3 = countNation(phead);
				printf("\n该民族的学生人数为：%d\n", count3);
				system("pause");
				break;
			}
			case 4: {
				Node_S *t;
				t = AgeCor(phead);
				system("pause");
				break;
			}
			case 5: {
				Node_S *t;
				t = NationCor(phead);
				system("pause");
				break;
			}
		default:
			continue;
		}
		system("pause");
	}
	return;
}


void menu2(Node_S* phead) {
	while (1) {
		system("CLS");
		printf("\n\t\t   学生信息查询功能");
		printf("\n\t\t--------------------");
		printf("\n\t\t   1 按年龄查询");
		printf("\n\t\t   2 按学号查询");
		printf("\n\t\t   3 按姓名查询");
		printf("\n\t\t   0 退出");
		printf("\n\t\t--------------------");
		printf("\n\t\t   请选择(0-3): ");
		int option;
		scanf("%d", &option);
		switch (option) {
			case 0: {
				return;
			}
			case 1: {
				printf("\n进入按年龄查询学生信息模块......");
				find_student_age(phead);
				break;
			}
			case 2: {
				printf("\n进入按学号查询学生信息模块......");
				find_student_sno(phead);
				break;
			}
			case 3: {
				printf("\n进入按姓名查询学生信息模块......");
				find_student_sname(phead);
				break;
			}
		default:
			continue;
		}
		system("pause");
	}
	return;
}



void menu3(Node_S* phead) {
	while (1) {
		system("CLS");
		printf("\n\t\t   学生信息排序功能");
		printf("\n\t\t--------------------");
		printf("\n\t\t   1 按学号排序");
		printf("\n\t\t   2 按年龄排序");
		printf("\n\t\t   3 按姓名排序");
		printf("\n\t\t   4 按民族排序");
		printf("\n\t\t   0 退出");
		printf("\n\t\t--------------------");
		printf("\n\t\t   请选择(0-4): ");
		int option;
		scanf("%d", &option);
		switch (option) {
			case 0: {
				return;
			}
			case 1: {
				printf("\n进入按学号排序模块......");
				sortSno(phead);
				break;
			}
			case 2: {
				printf("\n进入按年龄排序模块......");
				sortAge(phead);
				break;
			}
			case 3: {
				printf("\n进入按姓名排序模块......");
				sortSname(phead);
				break;
			}
			case 4: {
				printf("\n进入按民族排序模块......");
				sortNation(phead);
				break;
			}
		default:
			continue;
		}
		system("pause");
	}
	return;
}

void menu4(Node_S* phead) {
	while (1) {
		system("CLS");
		printf("\n\t\t   学生信息排序功能");
		printf("\n\t\t--------------------");
		printf("\n\t\t   1 插入到第一个学生前");
		printf("\n\t\t   2 插入到最后一个学生后");
		printf("\n\t\t   3 插入到指定学号学生前");
		printf("\n\t\t   0 退出");
		printf("\n\t\t--------------------");
		printf("\n\t\t   请选择(0-3): ");
		int option;
		scanf("%d", &option);
		switch (option) {
			case 0: {
				return;
			}
			case 1: {
				printf("\n进入“第一个学生前”模块......");
				addPhead(phead);
				printf("\n插入后：");
				Show(phead);
				break;
			}
			case 2: {
				printf("\n进入“插入最后一个学生后”模块......");
				addPtail(phead);
				printf("\n插入后：");
				Show(phead);
				break;
			}
			case 3: {
				printf("\n进入“插入到指定学生后”模块......");
				addAppoint(phead);
				printf("\n插入后：");
				Show(phead);
				break;
			}
		default:
			continue;
		}
		system("pause");
	}
	return;
}

void menu5(Node_S* phead) {
	while (1) {
		system("CLS");
		printf("\n\t\t   学生管理删除功能");
		printf("\n\t\t------------------------");
		printf("\n\t\t   1 删除第一个学生 <好用>");
		printf("\n\t\t   2 删除最后一个学生");
		printf("\n\t\t   3 删除给定学号的学生");
		printf("\n\t\t   0 退出");
		printf("\n\t\t------------------------");
		printf("\n\t\t   请选择(0-3): ");
		int option;
		scanf("%d", &option);
		switch (option) {
			case 0: {
				return;
			}
			case 1: {
				phead = Deletephead(phead);
				break;
			}
			case 2: {
				printf("\n进入删除尾模块......");
				phead = Deleteptail(phead);
				break;
			}
			case 3: {
				printf("\n进入按学号删除模块......");
				phead = DeleteAppoint(phead);
				break;
			}
		default:
			continue;
		}
		system("pause");
	}
	return;
}


void release(Node_S *phead) {
	Node_S *p = phead;
	while (p != NULL) {
		phead = phead->next;
		free(p);
		p = phead;
	}
	return;
}



Node_S* createList(Node_S* phead, int n) { //加参数
	
	for (int i = 0; i < n; i++) {
		Node_S *pnew = Add(phead);
		pnew->next = NULL;
		
		pnew->next = phead->next;
		phead->next = pnew;
	}
	
	return phead;
}


void traversal(Node_S *phead) {
	Node_S *p;
	p = phead->next;
	printf("学号\t\t姓名\t\t性别\t\t民族\t\t年龄\n");
	while (p != NULL) {
		printf("%d\t\t%s\t\t%s\t\t%s\t\t%d\n", p->data.sno, p->data.sname, p->data.gender, p->data.nation, p->data.age);
		p = p->next;
	}
	return;
}



int countGender(Node_S *phead) {    //自定义函数里（原则上）不允许有scanf和printf， 以下同！！！
	printf("\n程序功能：统计人数");
	printf("\n输入查询性别：");
	char b[3];
	scanf("%s", &b);
	getchar();
	Node_S *p;
	p = phead->next;
	int a = 0;
	while (p != NULL) {
		if (strcmp(p->data.gender, b) == 0) {
			a++;
		}
		p = p->next;
	}
	return a;
}

int countAge(Node_S* phead) {
	printf("\n程序功能：统计人数");
	printf("\n输入查询年龄：");
	int a;
	int b = 0;
	scanf("%d", &a);
	Node_S *p;
	p = phead->next;
	while (p != NULL) {
		if (p->data.age == a) {
			b++;
		}
		p = p->next;
	}
	return b;
}

int countNation(Node_S* phead) {
	printf("\n程序功能：统计人数");
	printf("\n输入查询的民族：");
	char a[10];
	scanf("%s", &a);
	getchar();
	int b = 0;
	Node_S *p;
	p = phead->next;
	while (p != NULL) {
		if (strcmp(a, p->data.nation) == 0) {
			b++;
		}
		p = p->next;
	}
	return b;
}

Node_S* AgeCor(Node_S *phead) {
	printf("\n程序功能：查询年龄对应的学生");
	printf("\n输入年龄：");
	int a;
	int b = 0;
	scanf("%d", &a);
	Node_S *p;
	p = phead->next;
	while (p != NULL) {
		if (p->data.age == a) {
			printf("\n学生信息：姓名：%s\n", p->data.sname);
			break;
		}
		p = p->next;
	}
	return p;
}


Node_S* NationCor(Node_S *phead) {
	printf("\n程序功能：查询民族对应的学生");
	printf("\n输入查询民族：");
	char a[10];
	scanf("%s", &a);
	getchar();
	Node_S *p;
	p = phead->next;
	while (p != NULL) {
		if (strcmp(a, p->data.nation) == 0) {
			printf("\n学生信息：姓名：%s\n", p->data.sname);
			break;
		}
		p = p->next;
	}
	return p;
}




Node_S* Deletephead(Node_S *phead) {
	Node_S *ps;
	ps = phead->next;
	if (phead->next == NULL) {
		phead->next = NULL;  //这是一句多余的话！！！！
		printf("已无学生信息！");   //不允许有printf的
	} else {
		phead->next = ps->next;
		ps->next = NULL;
		free(ps);  //释放啊 ！！！
		printf("\n删除后：");
		Show(phead);
	}
	
	return phead;
}


Node_S* Change(Node_S *phead) {
	Node_S *p;  // 创建一个链表节点p
	int f = 0;  // 记录是否找到匹配的链表节点
	
	int find;
	printf("请输入学号：");
	scanf("%d", &find);
	
	p = phead->next;  // 从链表的第一个节点开始
	while (p) {  // 遍历链表
		if (p->data.sno == find) { // 如果找到匹配的链表节点
			f = 1;  // 设置匹配标志为1
			printf("请输入修改后的姓名：");
			scanf("%s", &p->data.sname);
			printf("请输入修改后的性别：");
			scanf("%s", &p->data.gender);
			printf("请输入修改后的民族：");
			scanf("%s", &p->data.nation);
			printf("请输入修改后的年龄：");
			scanf("%d", &p->data.age);
			
			printf("\n修改后：");
			Show(phead);
		}
		p = p->next;  // 指向下一个节点
	}
	if (f == 0) {  // 如果没有找到匹配的链表节点
		printf("查无学生");  // 打印查无学生的提示信息
	}
	
	
	return phead;
}


void Show(Node_S *phead) {
	Node_S *p;
	p = phead->next;
	while (p != NULL) {
		printf("\n学号：%d 姓名：%s 性别：%s 民族：%s 年龄：%d", p->data.sno, p->data.sname, p->data.gender, p->data.nation, p->data.age);
		p = p->next;
	}
	printf("\n");
	return;
}

Node_S* Add(Node_S *phead) {
	Node_S* pnew = (Node_S*)malloc(sizeof(Node_S));
	printf("\n学号：");
	scanf("%d", &pnew->data.sno);
	printf("姓名：");
	scanf("%s", &pnew->data.sname);
	getchar();
	printf("性别：");
	scanf("%s", &pnew->data.gender);
	getchar();
	printf("民族：");
	scanf("%s", &pnew->data.nation);
	getchar();
	printf("年龄：");
	scanf("%d", &pnew->data.age);
	
	return pnew;
}

Node_S *sortSno(Node_S *phead) {
	
	Node_S *pre, *p, *t;  // 创建三个链表节点 pre, p, t
	int n = 0, i, j;  // 记录链表长度的变量 n，辅助循环的变量 i, j
	p = phead->next;  // 从链表头节点的下一位开始
// 计算链表长度
	while (p) {
		n++;  // 链表长度+1
		p = p->next;  // 指向下一个节点
	}
	for (i = 0; i < n - 1; i++) {  // 外层循环控制比较轮数
		p = phead->next;  // 重新指向链表的第一个节点
		pre = phead;  // pre指向链表的头节点
		for (j = 0; j < n - 1 - i; j++) {  // 内层循环进行相邻元素的比较
			if (p->data.sno > p->next->data.sno) {
				t = p->next;  // 交换两个链表节点的位置
				pre->next = t;
				p->next = t->next;
				t->next = p;
				p = t;  // 更新p为新的节点
			}
			p = p->next;  // 指向下一个节点
			pre = pre->next;  // 指向下一个节点
		}
	}
	traversal(phead);  // 调用traversal函数显示排序后的学生信息
	
	return phead;
}

Node_S *sortAge(Node_S *phead) {
	
	Node_S *pre, *p, *t;  // 创建三个链表节点 pre, p, t
	int n = 0, i, j;  // 记录链表长度的变量 n，辅助循环的变量 i, j
	p = phead->next;  // 从链表头节点的下一位开始
// 计算链表长度
	while (p) {
		n++;  // 链表长度+1
		p = p->next;  // 指向下一个节点
	}
	for (i = 0; i < n - 1; i++) {  // 外层循环控制比较轮数
		p = phead->next;  // 重新指向链表的第一个节点
		pre = phead;  // pre指向链表的头节点
		for (j = 0; j < n - 1 - i; j++) {  // 内层循环进行相邻元素的比较
			if (p->data.age > p->next->data.age) {
				t = p->next;  // 交换两个链表节点的位置
				pre->next = t;
				p->next = t->next;
				t->next = p;
				p = t;  // 更新p为新的节点
			}
			p = p->next;  // 指向下一个节点
			pre = pre->next;  // 指向下一个节点
		}
	}
	traversal(phead);  // 调用traversal函数显示排序后的学生信息
	
	return phead;
}

Node_S *sortSname(Node_S *phead) {
	
	Node_S *pre, *p, *t;  // 创建三个链表节点 pre, p, t
	int n = 0, i, j;  // 记录链表长度的变量 n，辅助循环的变量 i, j
	p = phead->next;  // 从链表头节点的下一位开始
// 计算链表长度
	while (p) {
		n++;  // 链表长度+1
		p = p->next;  // 指向下一个节点
	}
	for (i = 0; i < n - 1; i++) {  // 外层循环控制比较轮数
		p = phead->next;  // 重新指向链表的第一个节点
		pre = phead;  // pre指向链表的头节点
		for (j = 0; j < n - 1 - i; j++) {  // 内层循环进行相邻元素的比较
			if (strcmp(p->data.sname, p->next->data.sname) > 0) {
				t = p->next;  // 交换两个链表节点的位置
				pre->next = t;
				p->next = t->next;
				t->next = p;
				p = t;  // 更新p为新的节点
			}
			p = p->next;  // 指向下一个节点
			pre = pre->next;  // 指向下一个节点
		}
	}
	traversal(phead);  // 调用traversal函数显示排序后的学生信息
	
	return phead;
}

Node_S *sortNation(Node_S *phead) {
	
	Node_S *pre, *p, *t;  // 创建三个链表节点 pre, p, t
	int n = 0, i, j;  // 记录链表长度的变量 n，辅助循环的变量 i, j
	p = phead->next;  // 从链表头节点的下一位开始
// 计算链表长度
	while (p) {
		n++;  // 链表长度+1
		p = p->next;  // 指向下一个节点
	}
	for (i = 0; i < n - 1; i++) {  // 外层循环控制比较轮数
		p = phead->next;  // 重新指向链表的第一个节点
		pre = phead;  // pre指向链表的头节点
		for (j = 0; j < n - 1 - i; j++) {  // 内层循环进行相邻元素的比较
			if (strcmp(p->data.nation, p->next->data.nation) > 0) {
				t = p->next;  // 交换两个链表节点的位置
				pre->next = t;
				p->next = t->next;
				t->next = p;
				p = t;  // 更新p为新的节点
			}
			p = p->next;  // 指向下一个节点
			pre = pre->next;  // 指向下一个节点
		}
	}
	traversal(phead);  // 调用traversal函数显示排序后的学生信息
	
	return phead;
}

Node_S *addPhead(Node_S *phead) {
	Node_S *p = Add(phead);
	p->next = phead->next;
	phead->next = p;
	return phead;
}

Node_S *addPtail(Node_S *phead) {
	Node_S *p = Add(phead), *q;
	q = phead;
	while (q->next) {
		q = q->next;
	}
	q->next = p;
	p->next = NULL;
	return phead;
}

Node_S *addAppoint(Node_S *phead) {
	Node_S *p = Add(phead), *q;
	q = phead;
	int targetSno;
	printf("输入要插入的学生学号: ");
	scanf("%d", &targetSno);
	while (q->next && q->next->data.sno != targetSno) {
		q = q->next;
	}
	p->next = q->next;
	q->next = p;
	return phead;
}

Node_S *Deleteptail(Node_S *phead) {
	Node_S *p = phead;
	if (p->next == NULL) {
		return phead;
	}
	while (p->next->next) {
		p = p->next;
	}
	free(p->next);
	p->next = NULL;
	printf("\n删除后：");
	Show(phead);
	return phead;
}

Node_S *DeleteAppoint(Node_S *phead) {
	Node_S *p = phead, *q;
	int sno;
	printf("输入要删除的学生学号: ");
	scanf("%d", &sno);
	while (p->next) {
		if (p->next->data.sno == sno) {
			q = p->next;
			p->next = q->next;
			free(q);
			printf("\n删除后：");
			Show(phead);
			return phead;
		}
		p = p->next;
	}
	printf("\n删除后：");
	Show(phead);
	return phead;
}

void DataSave(Node_S *phead) {
	FILE *f;
	Node_S *p;
	f = fopen("Student_File.dat", "wb");
	p = phead->next;
	while (p) {
		fwrite(&(p->data), sizeof(Student), 1, f);
		p = p->next;
	}
	fclose(f);
}

/*
创建一个新的链表节点p，定义变量用于存储查询条件，通过用户输入，获取要查询的条件，将链表的头节点的下一位赋值给p，即第一个链表节点，使用循环遍历链表，直到链表末尾，在循环中，如果找到匹配的链表节点，则调用show_student函数，显示当前链表节点的信息，并将学生数目+1，将p指向下一个节点，以继续遍历链表的下一个节点，如果没有匹配的学生（f为0），则打印查无学生的提示信息。
*/
//按学号查询学生
void find_student_sno(Node_S *phead) {
	Node_S *p;  // 创建一个链表节点p
	int f = 0;  // 记录学生数目的变量
	
	int find;
	printf("请输入学号：");
	scanf("%d", &find);
	p = phead->next;
	while (p != NULL) {
		if (p->data.sno == find) {
			f = 1;
			printf("\n学号：%d 姓名：%s 性别：%s 民族：%s 年龄：%d", p->data.sno, p->data.sname, p->data.gender, p->data.nation, p->data.age);
		}
		p = p->next;
	}
	if (f == 0) {  // 如果没有学生（f为0）
		printf("查无学生");  // 打印查无学生的提示信息
	}
}
//按姓名查询学生
void find_student_sname(Node_S *phead) {
	Node_S *p;  // 创建一个链表节点p
	int f = 0;  // 记录学生数目的变量
	
	char find[40];
	printf("请输入姓名：");
	scanf("%s", &find);
	p = phead->next;
	while (p != NULL) {
		if (strcmp(p->data.sname, find) == 0) {
			f = 1;
			printf("\n学号：%d 姓名：%s 性别：%s 民族：%s 年龄：%d", p->data.sno, p->data.sname, p->data.gender, p->data.nation, p->data.age);
		}
		p = p->next;
	}
	if (f == 0) {  // 如果没有学生（f为0）
		printf("查无学生");  // 打印查无学生的提示信息
	}
}
//按年龄查询学生
void find_student_age(Node_S *phead) {
	Node_S *p;  // 创建一个链表节点p
	int f = 0;  // 记录学生数目的变量
	
	int find;
	printf("请输入年龄：");
	scanf("%d", &find);
	p = phead->next;
	while (p != NULL) {
		if (p->data.age == find) {
			f = 1;
			printf("\n学号：%d 姓名：%s 性别：%s 民族：%s 年龄：%d", p->data.sno, p->data.sname, p->data.gender, p->data.nation, p->data.age);
		}
		p = p->next;
	}
	if (f == 0) {  // 如果没有学生（f为0）
		printf("查无学生");  // 打印查无学生的提示信息
	}
}

